package account_manage

import (
	"fmt"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/widget"
	"github.com/atotto/clipboard"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go_gui/diy"
	"go_gui/g"
	"go_gui/lib"
	"golang.org/x/image/colornames"
	"sort"
	"strings"
	"time"
)

var (
	rankId2Keys = map[string][]string{
		"充值前100": {"总充值", "名字", "等级", "VIP", "binduid", "uid", "最后登录时间"},
		"等级前100": {"等级", "名字", "VIP", "binduid", "uid", "最后登录时间"},
		"战力前100": {"战力", "名字", "等级", "VIP", "binduid", "uid", "最后登录时间"},
	}

	key2Width = map[string]float32{
		"最后登录时间":  158,
		"总充值":     100,
		"名字":      200,
		"等级":      50,
		"VIP":     45,
		"binduid": 220,
		"uid":     245,
		"战力":      100,
	}

	gudShowKey = map[string]bool{
		"binduid":     true,
		"uid":         true,
		"name":        true,
		"lv":          true,
		"vip":         true,
		"maxzhanli":   true,
		"zhanli":      true,
		"lastloginip": true,
		"lasttime":    true,
		"hearttime":   true,
	}

	key2val = map[string]string{
		"最后登录时间": "lasttime",
		"名字":     "name",
		"等级":     "lv",
		"VIP":    "vip",
		"战力":     "maxzhanli",
	}
)

func getKey2Val(k string) (string, bool) {
	if k == "最后登录时间" && lib.InSlice(CurGameInfo.GameKey, []string{"heros", "mfm_wechat"}) {
		return "hearttime", true
	} else if k == "战力" && lib.InSlice(CurGameInfo.GameKey, G123GameKeyList) {
		return "zhanli", true
	} else {
		_res, ok := key2val[k]
		return _res, ok
	}
}

// chkAppendMenuItems 给排行视图添加可选操作
func chkAppendMenuItems(setKey, setVal string, userinfo map[string]any, cell fyne.CanvasObject) []*fyne.MenuItem {
	menuItems := make([]*fyne.MenuItem, 0)
	if lib.InSlice(setKey, []string{"uid", "binduid", "名字"}) {
		menuItems = append(
			menuItems,
			fyne.NewMenuItem("Copy", func() {
				clipboard.WriteAll(setVal)
				_msg := fmt.Sprintf("骚年!!!!!\n恭喜你，Copy成功~~~\nCopyKey: %s\nCopyValue: %s", setKey, setVal)
				diy.ShowLabelInfo(_msg, cell, time.Second*2)
			},
			),
		)
	}
	switch setKey {
	case "uid":
		// 非内网才有这个选项
		if !strings.Contains(CurServerInfo.DbHost, "10.0.0.") {
			menuItems = append(menuItems, fyne.NewMenuItem("复制该账号到内网", func() {
				CopyUser(setVal)
			}))
		}
		menuItems = append(menuItems, fyne.NewMenuItem("查询玩家信息", func() {
			ShowUserInfoView(setVal)
		}))
		menuItems = append(menuItems, fyne.NewMenuItem("归属地查询", func() {
			diy.ShowLabelInfo(lib.Ip2Address(userinfo["lastloginip"].(string)), cell, time.Second*2)
		}))
	}
	return menuItems
}

// RankView  游戏排行榜视图
func RankView() fyne.CanvasObject {
	// 排行榜展示table
	_dataTable := widget.NewTable(
		func() (int, int) {
			return 100, 0
		},
		func() fyne.CanvasObject {
			return diy.NewMenuLabel("")
		},
		func(id widget.TableCellID, object fyne.CanvasObject) {

		},
	)
	_dataTable.SetColumnWidth(0, 34)

	_sumMoneyText := canvas.NewText("", colornames.Red)
	_daySumMoneyText := canvas.NewText("", colornames.Red)
	_sumMoneyBox := container.NewHBox(
		widget.NewLabel("总充值:"),
		_sumMoneyText,
		widget.NewLabel("今日总充值:"),
		_daySumMoneyText,
	)
	AccountComp.SumMoneyBox = _sumMoneyBox

	// 排行下拉
	_rankSelectChange := func(rankKey string) {
		_loading := NewLoading("排行榜加载中", 80).Show()
		defer _loading.Hide()
		if rankKey != "充值前100" {
			AccountComp.SumMoneyBox.Hide()

		}
		_showKeys := rankId2Keys[rankKey]
		//_rankList := getRankList(s)
		var (
			_rankLen     int
			_rankList    []map[string]any
			_payRankList []*payInfo
		)

		if !IsNoServer() {
			switch rankKey {
			case "充值前100":
				_payRankList = getPayRankList()

				// 处理充值数据
				var sumMoney int
				var daySumMoney int
				_nt := g.C.Now()
				_zero := g.C.Zero(_nt)
				_uid2SumMoney := func() map[string]int {
					_uid2SumMoney := make(map[string]int)
					for _, payInfo := range _payRankList {
						if strings.Contains(payInfo.Orderid, "GM") {
							continue
						}
						_uid := payInfo.Uid
						_, ok := _uid2SumMoney[_uid]
						if !ok {
							_uid2SumMoney[_uid] = 0
						}

						// 魔法无敌特殊处理
						switch payInfo.Money.(type) {
						case string:
							switch payInfo.Money.(string) {
							case "libao1":
								payInfo.Money = 1
							case "libao3":
								payInfo.Money = 3
							case "libao6":
								payInfo.Money = 6

							}
						}

						intMoney := g.C.Any2Int(payInfo.Money)
						_uid2SumMoney[_uid] += intMoney
						sumMoney += intMoney
						if payInfo.Ctime >= _zero {
							daySumMoney += intMoney
						}
					}
					_sumMoneyText.Text = g.C.IntToString(sumMoney)
					_sumMoneyText.Refresh()
					_daySumMoneyText.Text = g.C.IntToString(daySumMoney)
					_daySumMoneyText.Refresh()
					return _uid2SumMoney
				}()

				// 按充值倒序排序，只取前100
				_fmtRankList := func() []*payInfo {
					_fmtRankList := make([]*payInfo, 0)
					for uid, sumMoney := range _uid2SumMoney {
						_fmtRankList = append(_fmtRankList, &payInfo{Uid: uid, SumMoney: sumMoney})
					}
					sort.Slice(_fmtRankList, func(i, j int) bool {
						return _fmtRankList[i].SumMoney > _fmtRankList[j].SumMoney
					})

					_rankMaxNum := 100
					if len(_fmtRankList) < _rankMaxNum {
						_rankMaxNum = len(_fmtRankList)
					}
					_fmtRankList = _fmtRankList[:_rankMaxNum]
					return _fmtRankList
				}()

				// 格式化排行榜玩家基本信息
				_uid2Info := func() map[string]map[string]any {
					_uidList := make([]string, 0)
					for _, payInfo := range _fmtRankList {
						_uidList = append(_uidList, payInfo.Uid)
					}
					_uid2Info := make(map[string]map[string]any)
					_option := &options.FindOptions{}
					_option.
						SetProjection(gudShowKey)
					_userList := g.Mdb.Find("userinfo", bson.M{"uid": bson.M{"$in": _uidList}}, _option)
					for _, user := range _userList {
						_uid2Info[user["uid"].(string)] = user
					}
					return _uid2Info
				}()

				for _, payInfo := range _fmtRankList {
					_userInfo, ok := _uid2Info[payInfo.Uid]
					if !ok {
						continue
					}
					_userInfo["总充值"] = payInfo.SumMoney
					_rankList = append(
						_rankList,
						_userInfo,
					)
				}

				AccountComp.SumMoneyBox.Show()

			case "等级前100":
				_rankList = getLvRankList()
			case "战力前100":
				_rankList = getZlRankList()
			}
		}

		_rankLen = len(_rankList)

		// 表格的行和列
		_dataTable.Length = func() (int, int) {
			return _rankLen + 1, len(_showKeys) + 1
		}
		// 创建格子
		_dataTable.CreateCell = func() fyne.CanvasObject {
			return diy.NewMenuLabel("")
		}
		// 更新格子
		_dataTable.UpdateCell = func(id widget.TableCellID, cell fyne.CanvasObject) {
			menuLabel := cell.(*diy.MenuLabel)
			menuLabel.Clear()
			// 排名序列
			if id.Col == 0 {
				menuLabel.SetText(fmt.Sprintf("%d", id.Row+1))

			}

			// 表头
			if id.Row == 0 {
				if id.Col > 0 {
					menuLabel.SetText(fmt.Sprintf("%s", _showKeys[id.Col-1]))
				}
			} else {
				if id.Col >= 1 {
					_idx := id.Row - 1
					_setKey := _showKeys[id.Col-1]
					_toKey, ok := getKey2Val(_setKey)
					var _setVal string
					var anyVal any
					_userInfo := _rankList[_idx]
					if ok {
						anyVal = _userInfo[_toKey]
					} else {
						anyVal = _userInfo[_setKey]
					}
					switch _setKey {
					case "最后登录时间":
						if anyVal == nil {
							anyVal = int32(0)
						}
						_setVal = g.C.Now2Date(int64(anyVal.(int32)))
					default:
						_setVal = g.C.Any2String(anyVal)

					}
					menuLabel.SetText(_setVal)
					// 设置扩展按钮
					menuLabel.SetMenuItems(chkAppendMenuItems(_setKey, _setVal, _userInfo, cell)...)

				}
			}

		}

		// 设置表头宽度
		for idx, key := range _showKeys {
			_dataTable.SetColumnWidth(idx+1, key2Width[key])
		}
		// 刷新排行榜
		_dataTable.Refresh()
	}
	_rankSelect := widget.NewSelect(
		[]string{
			"充值前100",
			"等级前100",
			"战力前100",
		},
		_rankSelectChange,
	)
	// 记录到全局
	AccountComp.RankSelect = _rankSelect
	// 默认选第一个
	_rankSelect.SetSelectedIndex(2)

	_selectBox := container.NewHBox(
		widget.NewLabel("请选择排行榜:"),
		_rankSelect,
		_sumMoneyBox,
	)
	view := container.NewBorder(_selectBox, nil, nil, nil, _dataTable)

	return view
}

type payInfo struct {
	Uid      string
	Money    any
	SumMoney int
	Ctime    int64
	Orderid  string
}

// getPayRankList 获取充值排行榜
func getPayRankList() []*payInfo {
	_rankList := make([]*payInfo, 0)
	_option := &options.FindOptions{}
	_option.SetProjection(map[string]bool{
		"money":   true,
		"uid":     true,
		"ctime":   true,
		"orderid": true,
	})
	g.Mdb.FindByReflect("paylist", bson.M{}, &_rankList, _option)

	return _rankList
}

// getLvRankList 获取等级排行榜
func getLvRankList() []map[string]any {
	_option := &options.FindOptions{}
	_option.
		SetProjection(gudShowKey).
		SetSort(bson.M{
			"lv": -1,
		}).
		SetLimit(100)
	_rankList := g.Mdb.Find("userinfo", bson.M{}, _option)

	return _rankList
}

// getZlRankList 获取战力排行榜
func getZlRankList() []map[string]any {
	_option := &options.FindOptions{}
	sortDict := bson.M{
		"maxzhanli": -1,
	}
	switch CurGameInfo.GameKey {
	case "jya":
		sortDict = bson.M{
			"zhanli": -1,
		}
	}
	_option.
		SetProjection(gudShowKey).
		SetSort(sortDict).
		SetLimit(100)
	_rankList := g.Mdb.Find("userinfo", bson.M{}, _option)

	return _rankList
}
